using System;
using System.Collections.Generic;
using System.Data;

namespace Dbam.DbFramework
{
	[AttributeUsage(AttributeTargets.Property, AllowMultiple=true, Inherited=true)]
	public class RelationAttribute
		: Attribute
	{
		private string _parentColumnName;
		private string _relatedTableName;
		private string _relatedColumnName;
		private Type _relatedEntityType;
		private Type _ormForRelatedEntityType;
		private IDbFactory _dbFactory;

		public RelationAttribute(string parentColumnName, string relatedTableName, string relatedColumnName, Type relatedEntityType)
		{
			if(parentColumnName == null)
				throw new ArgumentNullException("parentColumnName");
			if(relatedTableName == null)
				throw new ArgumentNullException("relatedTableName");
			if(relatedColumnName == null)
				throw new ArgumentNullException("relatedColumnName");
			if(relatedEntityType == null)
				throw new ArgumentNullException("relatedEntityType");

			_parentColumnName = parentColumnName;
			_relatedTableName = relatedTableName;
			_relatedColumnName = relatedColumnName;
			_relatedEntityType = relatedEntityType;

			// Check if the related entity type is createable
			if(_relatedEntityType.GetConstructor(Type.EmptyTypes) == null)
				throw new InvalidProgramException(ErrorStrings.EntityNotCreatable);

			// Construct the ORM type for the related entity type (.NET 2.0 is so cool for this!)
			Type ormType = typeof(ObjectRelationalMapper<>); // <-- this works!
			_ormForRelatedEntityType = ormType.MakeGenericType(new Type[] { _relatedEntityType });
		}

		public string ParentColumnName
		{
			get { return _parentColumnName; }
		}

		public string RelatedTableName
		{
			get { return _relatedTableName; }
		}

		public string RelatedColumnName
		{
			get { return _relatedColumnName; }
		}

		public Type RelatedEntityType
		{
			get { return _relatedEntityType; }
		}

		public Type ORMForRelatedEntityType
		{
			get { return _ormForRelatedEntityType; }
		}

		internal IDbFactory DbFactory
		{
			get { return _dbFactory; }
			set { _dbFactory = value; }
		}
	}
}